Imports System.Linq.Expressions
Imports WPFSearchDataGrid.Assets
Imports LinqKit

Public Class Record
    
    Private m_properties As Dictionary(Of String, IDataItem) = New Dictionary(Of String, IDataItem)()

    Public Sub New(dataitems As IEnumerable(Of IDataItem))
        For Each var As IDataItem In dataitems
            m_properties.Add(var.DataPropertyName, var)
        Next

    End Sub

    Public Property Properties As Dictionary(Of String, IDataItem)
        Get
            Return m_properties
        End Get
        Set(value As Dictionary(Of String, IDataItem))
            m_properties = value
        End Set
    End Property

    Public Sub New()
    End Sub

    Public Overloads Function FilterAsExpression(Of T)() As Expression(Of Func(Of T, Boolean))
        Dim pred = PredicateBuilder.True(Of T)()
        'maybe promote _propertyinfocollection to class variable to performance?
        Dim _propertyinfocollection() As Reflection.PropertyInfo = GetType(T).GetProperties()
        For Each di As KeyValuePair(Of String, IDataItem) In m_properties
            Dim obj As IDataItem = di.Value
            If IsNothing(obj.Value) Then Continue For
            Dim _propertyinfo As Reflection.PropertyInfo = _propertyinfocollection.First(Function(e) e.Name = obj.DataPropertyName)
            Dim func = obj.FilterAsExpression(Of T)(_propertyinfo)
            If IsNothing(func) Then Continue For
            pred = pred.And(func)
        Next
        Return pred
    End Function

    Public Overloads Function FilterAsString(Of T)() As String
        Dim _sb As New List(Of String)
        Dim _propertyinfocollection() As Reflection.PropertyInfo = GetType(T).GetProperties()
        For Each di As KeyValuePair(Of String, IDataItem) In m_properties
            Dim obj As IDataItem = di.Value
            If IsNothing(obj.Value) Then Continue For
            Dim _propertyinfo As Reflection.PropertyInfo = _propertyinfocollection.First(Function(e) e.Name = obj.DataPropertyName)
            _sb.Add(obj.FilterAsString(Of T)(_propertyinfo))
        Next
        Return String.Join(" AND ", _sb)
    End Function

End Class